<script lang="ts" setup>
import { ElTable, FormInstance, FormRules } from 'element-plus';
import { nextTick } from 'vue';
import { createRole, getPermissionTree1, updateRole } from '@/api';
import { Menu, Role } from '@/model';
import { errorNotice } from '@/libs/utils';
import { listChildren, listParent, setSelected, toList } from '@/libs/utils/menuUtil';

const props = defineProps<{
  // 是否打开弹出层
  visible: boolean;
  // 什么动作触发的弹窗？create：新增；update：编辑
  type: string;
  // 当前被点击的行，用作编辑，或新增
  currentRow: Role | undefined;
}>();

const emits = defineEmits(['closeDialog', 'submitted']);

const dialogHeight = ref<string>('');
const form = reactive<Role>({});
const formRef = ref<FormInstance>();
// 权限列表树形结构
const permissionTree = ref<Array<Menu>>([]);
// 权限列表，平面数组
const permissionList = ref<Array<Menu>>([]);
const treeRef = ref<InstanceType<typeof ElTable>>();

const rules = reactive<FormRules>({
  roleName: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
  enabled: [{ required: true, message: '请选择是否启用', trigger: 'blur' }],
});

/**
 * 当一行被点击时
 * @param row
 */
const onRowClick = (row: Menu) => {
  // 超管点击不做反馈
  if (form.superRole) return;
  if (!treeRef.value) return;
  if (form.permissionIds && form.permissionIds.indexOf(row.id) > -1) {
    treeRef.value.toggleRowSelection(row, false);
  } else {
    // 把当前节点的父辈节点和子孙节点都添加到被选中的列表中
    let parents = listParent(row, permissionList.value);
    const children = listChildren(row, permissionList.value);
    parents = [...parents, ...children];
    parents.push(row);
    if (parents.length) {
      const parentIds = parents.map((item: Menu) => item.id);
      if (!form.permissionIds) {
        form.permissionIds = [];
      }
      form.permissionIds = [...form.permissionIds, ...parentIds];
      setSelected(permissionTree.value, form.permissionIds, treeRef.value);
    }
  }
};

/**
 * 当复选框被点击时
 * @param selection
 * @param row
 */
const onSelect = (selection: Array<Menu>, row: Menu) => {
  onRowClick(row);
};

/**
 * 当选项发生变化时，这里更新被选中的选项
 * @param selection
 */
const onSelectionChange = (selection: Array<Menu>) => {
  form.permissionIds = selection.map((item: Menu) => item.id);
};

/**
 * 关闭弹窗，更新默认值
 */
const onClose = () => {
  emits('closeDialog', false, undefined);
  if (!formRef || !formRef.value) {
    return;
  }
  formRef.value.resetFields();
};

/**
 * 新增或编辑提交
 */
const onSubmit = async () => {
  if (!formRef.value) return;
  await formRef.value.validate((valid, fields) => {
    if (valid) {
      if (props.type === 'update') {
        updateRole(form).then(() => {
          emits('submitted');
        });
      } else {
        createRole(form).then(() => {
          emits('submitted');
        });
      }
    } else {
      errorNotice(fields);
    }
  });
};

/**
 * 计算滚动条高度
 */
const calcScrollbarHeight = () => {
  dialogHeight.value = `${window.innerHeight * 0.5}px`;
};

/**
 * 当弹出层被打开时触发
 */
const onOpen = () => {
  calcScrollbarHeight();
  form.enabled = true;
  // 编辑
  if (props.type === 'update') {
    form.id = props.currentRow!.id;
    form.roleName = props.currentRow!.roleName;
    form.description = props.currentRow!.description;
    form.enabled = props.currentRow!.enabled;
    form.permissionIds = props.currentRow!.permissionIds;
    form.superRole = props.currentRow!.superRole;
    getPermissionTree1([]).then((res: Array<Menu>) => {
      permissionTree.value = res;
      permissionList.value = toList(res);
      nextTick(() => {
        setSelected(res, props.currentRow!.permissionIds, treeRef.value);
      });
    });
  } else {
    form.id = undefined;
    getPermissionTree1([]).then((res: Array<Menu>) => {
      permissionList.value = toList(res);
      permissionTree.value = res;
    });
  }
};
</script>

<template>
  <el-dialog
    :model-value="visible"
    :show-close="false"
    @closed="onClose"
    width="60%"
    @open="onOpen"
    :close-on-click-modal="false"
  >
    <template #header>
      <div class="form-header">
        <span class="title">{{ type === 'update' ? '编辑' : '新增' }}</span>
        <div>
          <el-tooltip content="确认" placement="top" effect="light" :show-after="500">
            <el-button
              class="btn-confirm"
              circle
              @click="onSubmit()"
              v-show="!form.superRole"
            >
              <el-icon>
                <i-ep-check />
              </el-icon>
            </el-button>
          </el-tooltip>
          <el-tooltip content="取消" placement="top" effect="light" :show-after="500">
            <el-button class="btn-cancel" circle @click.stop="onClose()">
              <el-icon>
                <i-ep-close />
              </el-icon>
            </el-button>
          </el-tooltip>
        </div>
      </div>
    </template>
    <el-scrollbar :height="dialogHeight" ref="scrollbarRef">
      <el-form
        ref="formRef"
        :model="form"
        :rules="rules"
        label-width="120px"
        class="form"
        size="large"
        :show-message="false"
        :disabled="form.superRole"
      >
        <el-row :gutter="10">
          <el-col :span="12">
            <el-form-item label="角色名称" prop="roleName">
              <el-input v-model="form.roleName" class="form-input" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="角色描述" prop="description">
              <el-input v-model="form.description" class="form-input" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="10">
          <el-col :span="12">
            <el-form-item label="启用" prop="enabled">
              <el-switch v-model="form.enabled" />
            </el-form-item>
          </el-col>
          <el-col :span="12"></el-col>
        </el-row>
        <el-table
          :data="permissionTree"
          style="width: 100%; margin-bottom: 20px"
          row-key="id"
          ref="treeRef"
          default-expand-all
          @select="onSelect"
          @row-click="onRowClick"
          @selection-change="onSelectionChange"
          :indent="20"
        >
          <el-table-column width="55" type="selection" />
          <el-table-column prop="name" label="权限名称" />
          <el-table-column prop="type" label="权限类型" width="100px">
            <template #default="scope">
              {{ scope.row.type === 1 ? '菜单' : '按钮' }}
            </template>
          </el-table-column>
          <el-table-column prop="iconName" label="图标" width="80px">
            <template #default="scope">
              <el-icon size="20px">
                <component :is="scope.row.iconName" />
              </el-icon>
            </template>
          </el-table-column>
          <el-table-column prop="iconColor" label="图标颜色" width="100px">
            <template #default="scope">
              <div
                :style="
                  'width: 20px; height: 20px; background-color: ' + scope.row.iconColor
                "
              ></div>
            </template>
          </el-table-column>
          <el-table-column prop="url" label="权限路径" />
          <el-table-column prop="description" label="备注" />
        </el-table>
      </el-form>
    </el-scrollbar>
  </el-dialog>
</template>

<style scoped lang="scss"></style>
